﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IsreversI
{
    struct PlayerColour
    {
        private enum State
        {
            red = 1,
            blue = 2,
            invalid = 128 // something suitably large and unlikely to occur at random
        }

        #region member variables
        private State state;
        #endregion

        #region static instances
        public static readonly PlayerColour Red = new PlayerColour(State.red);
        public static readonly PlayerColour Blue = new PlayerColour(State.blue);
        public static readonly PlayerColour Invalid = new PlayerColour(State.invalid);
        #endregion

        #region constructors
        private PlayerColour(State state)
        {
            this.state = state;
        }
        #endregion

        #region public functions
        public PlayerColour Flipped()
        {
            if (this == Red)
                return Blue;
            else if (this == Blue)
                return Red;
            Debug.Assert(false, "Cannot invert state " + state);
            return Invalid;
        }

        public bool Equals(PlayerColour s)
        {
            return this.state == s.state;
        }
        #endregion

        #region overides
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            PlayerColour s = (PlayerColour)obj;
            return this.state == s.state;
        }

        public override int GetHashCode()
        {
            return (int)this.state;
        }

        public override string ToString()
        {
            switch (this.state)
            {
                case State.red:
                    return "Red";
                case State.blue:
                    return "Blue";
                default:
                    return "Invalid";
            }
        }
        #endregion

        #region operator overloads
        static public PlayerColour operator ~(PlayerColour state)
        {
            return state.Flipped();
        }

        static public bool operator ==(PlayerColour f, PlayerColour s)
        {
            return f.Equals(s);
        }

        static public bool operator !=(PlayerColour f, PlayerColour s)
        {
            return !f.Equals(s);
        }

        public static explicit operator TileState(PlayerColour colour)
        {
            if (colour == Red)
                return TileState.Red;
            else if (colour == Blue)
                return TileState.Blue;
            Debug.Assert(false, "Cannot convert colour " + colour);
            return TileState.Invalid;
        }
        #endregion
    }
}
